//
// layoutComposer.js：电路页面组件
//

import {
  Layout as LayoutDHX,
  Toolbar as ToolbarDHX,
  Form as FormDHX,
  Window as WindowDHX,
} from 'dhx-suite-package';
import { Message, Alert } from '@/components/message';
import FileSaver from 'file-saver';
import fileModule from '@/store/module/file';
import simulationModule from '@/store/module/simulation';
import { basicSetup } from 'codemirror';
import { EditorView, keymap } from '@codemirror/view';
import { indentWithTab } from '@codemirror/commands';
import QComposer from './QComposer';

const LayoutComposer = ({
  barHeight: 37,

  // 0. 整体布局（两栏式）
  layoutContainer: null,
  activeFile: {},

  // 1. 左侧代码
  // 1.1. 代码工具栏
  toolbarCode: null,
  // 1.2. 代码输入
  richtextCode: null,
  // 1.3. 代码文件上传
  windowUpload: null,
  formUpload: null,

  // 2. 右侧可视化
  layoutVisual: null,

  // ///////////////////////////////////////
  // init 函数被ComposerView.vue调用，在用户选择了文件之后
  init() {
    // 0. 整体布局（两栏式）///////////////
    this.layoutContainer = this.layoutContainer_create();
    this.layoutContainer_event();

    // 1. 左侧代码 ///////////////////////
    // 1.1. 代码工具栏
    this.toolbarCode = this.toolbarCode_create();
    this.toolbarCode_event();
    // 1.2. 代码输入
    this.richtextCode_create();
    // 1.3. 代码文件上传
    this.windowUpload = this.windowUpload_create();
    this.formUpload = this.formUpload_create();
    this.formUpload_event();

    // 2. 右侧可视化 //////////////////////
    this.layoutVisual = QComposer.init();

    // 挂载各组件 /////////////////////////
    // 1. 左侧代码
    // 1.1. 代码工具栏
    this.layoutContainer.getCell('toolbarCode').attach(this.toolbarCode);
    // 1.2. 代码框在create的时候自动挂载
    // 1.3. 文件上传
    this.windowUpload.attach(this.formUpload);
    // 2. 右侧可视化
    this.layoutContainer.getCell('visualContainer').attach(this.layoutVisual);

    return this.layoutContainer;
  },

  // ///////////////////////////////////////
  // 0. 整体布局
  // ///////////////////////////////////////
  layoutContainer_create() {
    const mylayout = new LayoutDHX(null, {
      type: 'line',
      cols: [
        {
          width: '20%',
          resizable: true,
          rows: [
            {
              id: 'toolbarCode',
              height: this.barHeight,
              collapsable: false,
              resizable: false,
            }, {
              id: 'richtextCode',
              height: '95%',
              collapsable: false,
              resizable: false,
              html: '<div id="code"></div>',
            },
          ],
        }, {
          id: 'visualContainer',
          width: '80%',
          collapsable: false,
          resizable: false,
        },
      ],
    });
    return mylayout;
  },
  layoutContainer_event() {
    const that = this;
    const myevents = that.layoutContainer.events;
    myevents.on('afterResizeEnd', (id) => {
      console.log('layoutComposer', id);
      // TODO：改变代码和可视化的页面占比大小后，重新刷新可视化面板
      // var size = that.layoutContainer.getCell("visualContainer").getSize();
      // console.log(size);
    });
  },
  // ///////////////////////////////////////
  // 1. 左侧代码
  // ///////////////////////////////////////
  // 1.1. 代码工具栏
  toolbarCode_create() {
    const mytoolbar = new ToolbarDHX('toolbar', {
      navigationType: 'pointer',
      data: [
        {
          id: 'upload',
          html: '<i class="fa-solid fa-upload"></i>',
          tooltip: '上传代码',
        }, {
          id: 'download',
          html: '<i class="fa-solid fa-download"></i>',
          tooltip: '下载代码',
        }, {
          id: 'save',
          html: '<i class="fa-solid fa-floppy-disk"></i>',
          tooltip: '保存代码',
        }, {
          type: 'spacer',
        }, {
          id: 'compile',
          type: 'button',
          html: '<i class="fa-solid fa-gear"></i> 生成线路',
          tooltip: '生成线路',
          twoState: false,
          circle: true,
          css: 'toolbar_btn_style',
        },
      ],
      css: 'toolbar_style',
    });
    return mytoolbar;
  },
  toolbarCode_event() {
    const that = this;
    const myevents = that.toolbarCode.events;
    myevents.on('click', (id) => {
      switch (id) {
        case 'upload':
          that.windowUpload.show();
          break;
        case 'download': // 获取textarea内容并下载
          FileSaver.saveAs(new Blob([that.richtextCode_get()], { type: 'text/plain' }), `${that.activeFile.name}.txt`);
          break;
        case 'save':
          that.fsave();
          break;
        case 'compile':
          that.fcompile();
          break;
        default: break;
      }
    });
  },
  // 挂载代码编辑框
  richtextCode_create() {
    const that = this;
    let code = document.getElementById('code');
    if (code) {
      that.richtextCode = that.richtextCode_init(); // 加载代码框
    } else {
      const checkCode = setInterval(() => {
        code = document.getElementById('code');
        if (code) {
          clearInterval(checkCode); // 清空定时器
          that.richtextCode = that.richtextCode_init(); // 加载代码框
        }
      }, 100);
    }
  },
  // 初始化codemirror编辑器
  richtextCode_init() {
    const mycode = new EditorView({
      extensions: [
        basicSetup,
        keymap.of([indentWithTab]),
        EditorView.theme({
          '&.cm-editor .cm-content': {
            fontFamily: 'Consolas',
          },
          '&.cm-editor.cm-focused': {
            outline: 'none',
          },
          '.cm-gutters': {
            backgroundColor: '#fff',
          },
        }),
      ],
      parent: document.getElementById('code'), // 编辑器 挂载的dom
    });
    return mycode;
  },
  richtextCode_set(code) {
    const that = this;
    if (that.richtextCode) {
      that.richtextCode.dispatch({
        changes: { from: 0, to: that.richtextCode.state.doc.length, insert: code },
      });
    } else {
      const checkCode = setInterval(() => {
        if (that.richtextCode) {
          clearInterval(checkCode); // 清空定时器
          that.richtextCode.dispatch({
            changes: { from: 0, to: that.richtextCode.state.doc.length, insert: code },
          });
        }
      }, 100);
    }
  },
  richtextCode_get() {
    const that = this;
    return that.richtextCode.state.doc.toString();
  },
  // 1.3. 代码文件上传
  windowUpload_create() {
    const mywindow = new WindowDHX({
      modal: true,
      title: '上传代码文件',
      closable: true,
      width: 360,
      height: 360,
    });
    return mywindow;
  },
  formUpload_create() {
    const myform = new FormDHX('formUpload', {
      rows: [
        {
          type: 'simpleVault',
          id: 'file',
          required: true,
          preMessage: '请上传.txt格式的文件（小于64KB）',
          errorMessage: '请上传.txt格式的文件（小于64KB）',
          hiddenLabel: true,
        }, {
          align: 'center',
          cols: [
            {
              type: 'button',
              id: 'send',
              text: '确认',
              submit: true,
              full: true,
            },
          ],
        },
      ],
    });
    return myform;
  },
  formUpload_event() {
    const that = this;
    const myform = that.formUpload;
    const myvault = myform.getItem('file');
    // a. 文件上传
    myvault.data.events.on('beforeAdd', (item) => {
      myvault.clear(); // 替换上一个上传的文件
      // 检查文件格式(.txt)和大小(64KB)
      return item.file.type == 'text/plain' && item.file.size < 65536;
    });
    myvault.data.events.on('afterAdd', (file) => {
      console.log('afterAdd', typeof (file), file);
    });
    // b. 文件发送
    myform.getItem('send').events.on('click', () => {
      // 判断表单是否合法
      if (myform.validate()) {
        // 获取文件名和文件内容
        const formState = {};
        formState.id = that.activeFile.id;
        formState.file = myvault.getValue()[0].file;
        // 上传文件
        fileModule.actions.fupload(null, formState).then((res) => {
          Message('文件上传成功');
          that.windowUpload.hide(); // 关闭表单弹窗
          that.richtextCode_set(res.data.data.file.content);
        }).catch((err) => {
          Alert(err.response.data.msg);
        });
      }
    });
  },
  // ///////////////////////////////////
  // 后端交互
  // ///////////////////////////////////
  fsave() { // 保存当前代码
    const that = this;
    const formState = {};
    formState.id = that.activeFile.id;
    formState.content = that.richtextCode_get();
    fileModule.actions.fsave(null, formState).then(() => { Message(`保存${that.activeFile.name}成功`); })
      .catch((err) => { Alert(err.response.data.msg); });
  },

  fcompile() {
    const that = this;
    const formState = {};
    formState.id = that.activeFile.id;
    formState.content = that.richtextCode_get();
    fileModule.actions.fsave(null, formState) // 保存文件
      .then(() => {
        formState.content = null;
        return simulationModule.actions.compile(null, formState); // 编译文件
      }).then((res) => {
        const circuit = res.data.data; // 获取线路抽象
        console.log('compile: ', circuit);
        QComposer.circuit_reload(circuit); // 绘图
        Message('代码解析成功');
      }).catch((err) => {
        Alert(err.response.data.msg);
      });
  },
});

export default LayoutComposer;
